<?php
/**
 * @author spenceryg
 * @date 2023/4/4
 * @time 8:58 上午
 * @focus love & life
 */


namespace app\api\controller;


use app\common\lib\Crontab;
use app\common\model\PushLog;
use app\common\model\PushPlan;
use hg\apidoc\annotation as Apidoc;

/**
 * Class Plan
 * @package app\api\controller
 * @Apidoc\Title("发布计划")
 * @Apidoc\Group("api")
 */
class Plan extends Auth
{
    /**
     * list
     * @Apidoc\Title("计划列表")
     */
    public function list()
    {
        $list_rows = input('list_rows', 10, 'intval');
        $where = [];

        $where[] = ['member_id', '=', $this->request->uid];

        $period_map = [
            1=> '每天',
            2=> '每周',
            3=> '每月',
        ];

        $weekday_map = [
            1 => '周一',
            2 => '周二',
            3 => '周三',
            4 => '周四',
            5 => '周五',
            6 => '周六',
            7 => '周日',            
        ];

        $res = PushPlan::where($where)->order("id desc")->paginate($list_rows);
        $res = $res->toArray();
        foreach ($res['data'] as $index => $item) {
            $item['period_str'] = $period_map[$item['period']];
            if($item['period'] == 2) {
                $weekday_arr = explode(",", $item['week']);
                $week_arr = [];
                foreach ($weekday_arr as $week) {
                    $week_arr[] = $weekday_map[$week];
                }
                $item['period_str'] .=  ':' . implode(',', $week_arr);
            }
            if($item['period'] == 3) {
                $item['period_str'] .= $item['day'];
            }
            if($item['hour']<12){
                
            }
            $item['time_str'] = ($item['hour']<12?"上午 ":"下午 ").$item['hour'] . '点' . $item['minute'] . '分';
            //计划下对应的分类文章数量
            $item['article_num'] = \app\common\model\Article::where([
                ["state","=",2],//待发布的
                ["article_class_id","=",$item['article_class_id']]
            ])->count();
            $item['site_name'] = \app\common\model\Site::where('id', $item['site_id'])->value('name');
            $item['total'] = PushLog::where('push_plan_id', $item['id'])
                ->where('state', 1)
                ->count('id');
            $res['data'][$index] = $item;
        }
        return success('ok',$res);
    }

    /**
     * add
     * @Apidoc\Title("添加计划")
     */
    public function add()
    {
        $data = input();
        validate([
            'name|计划名称' => 'require',
            'number_of_articles|文章数量' => 'require',
            'article_class_id|文章分类' => 'require',
            'period|执行周期' => 'require',
            'hour|执行时间-小时' => 'require',
            'minute|执行时间-分钟' => 'require',
            'site_id|网站站点' => 'require',
            'site_cat_id|网站栏目' => 'require',
        ] )->check($data);
        iF($data['is_insert_picture'] && !$data['img_class_id']) {
            return error('图片分类不能为空');
        }
        if($data['period'] == 2 && !$data['week']) {
            return error('执行周期-星期不能为空');
        }
        if($data['period'] == 3 && !$data['day']) {
            return error('执行周期-日期不能为空');
        }
        if(!$data['number_of_articles']) {
            return error('文章条数要大于0');
        }          
        if(is_array($data['week'])) {
            $data['week'] = implode(',', $data['week']);
        }
        $data['member_id'] = $this->request->uid;
        $data['relation_num'] = json_encode($data['relation_num']);
        $plan = PushPlan::create($data);
        
        if($plan['is_open']){
            $cron = $this->getCronJob($plan->getData());
            Crontab::addJob($cron);
        }
        return success();
    }


    /**
     * getCronJob
     * @param $plan
     * @return string
     */
    private function getCronJob($plan): string
    {
        $job = config('wechat.base_url'). '/api/cron/doPlan?id=';
        //  每天
        if($plan['period'] == 1) {
            $plan['day'] = '*';
            $plan['month'] = '*';
            $plan['week'] = '*';
        }
        // 每周
        if($plan['period'] == 2) {
            $plan['month'] = '*';
            $plan['day'] = '*';
        }
        // 每月
        if($plan['period'] == 3) {
            $plan['week'] = '*';
            $plan['month'] = '*';
        }
        $time = $plan['minute'] . ' ' . $plan['hour'] . ' ' . $plan['day'] . ' ' .  $plan['month'] . ' ' .  $plan['week'] . ' ';
        return $time . 'curl ' . $job . $plan['id'];
    }

    /**
     * update
     * @Apidoc\Title("更新计划")
     */
    public function update()
    {
        $data = input();
        validate([
            'name|计划名称' => 'require',
            'number_of_articles|文章数量' => 'require',
            'article_class_id|文章分类' => 'require',
            'is_insert_picture|图片分类' => 'require',
            'period|执行周期' => 'require',
            'hour|执行时间-小时' => 'require',
            'minute|执行时间-分钟' => 'require',
            'site_id|网站站点' => 'require',
            'site_cat_id|网站栏目' => 'require',
        ] )->check($data);
        iF($data['is_insert_picture'] && !$data['img_class_id']) {
            return error('图片分类不能为空');
        }
        if($data['period'] == 2 && !$data['week']) {
            return error('执行周期-星期不能为空');
        }
        if(!$data['number_of_articles']) {
            return error('文章条数要大于0');
        }        
        if($data['period'] == 3 && !$data['day']) {
            return error('执行周期-日期不能为空');
        }
        if(is_array($data['week'])) {
            $data['week'] = implode(',', $data['week']);
        }
        $data['member_id'] = $this->request->uid;
        $data['relation_num'] = json_encode($data['relation_num']);

        // 删除之前的定时任务
        $plan = PushPlan::find($data['id']);
        $cron = $this->getCronJob($plan->getData());
        Crontab::removeJob($cron);

        // 更新任务表
        $plan = PushPlan::update($data);

        // 添加新的任务
        if($plan['is_open']){
            $cron = $this->getCronJob($plan->getData());
            Crontab::addJob($cron);
        }
        return success();
    }


    /**
     * getContent
     *  @Apidoc\Title("获取计划详情")
     */
    public function getContent()
    {
        $id = input('id');
        $plan = PushPlan::find($id);
        if($plan['member_id'] != $this->request->uid) {
            return error('非法请求');
        }
        unset($plan['delete_time']);
        unset($plan['update_time']);
        unset($plan['create_time']);
        unset($plan['pubid']);
        unset($plan['sort']);
        $plan['relation_num'] = json_decode($plan['relation_num']);
        //不要问我这里为什么要array_map，因为直接explode输出的数据元素为string类型，el-select只认int，弄半天才知道！！！
        $plan['week'] = explode(",",$plan['week']);
        $plan['week'] = array_map('intval', $plan['week']);
        return success('', $plan);
    }

    /**
     * delete
     * @Apidoc\Title("删除计划")
     */
    public function delete(): \think\response\Json
    {
        $id = input('id');
        $plan = PushPlan::find($id);
        if($plan['member_id'] != $this->request->uid) {
            return error('非法请求');
        }
        $cron = $this->getCronJob($plan->getData());
        Crontab::removeJob($cron);
        PushPlan::destroy($id);
        return success();
    }
}
